<?php

namespace ticky\session\driver;

use SessionHandler;

class Mysql extends SessionHandler {

    private $lifetime = 18000;
    private $table;

    public function __construct() {

    }

    /**
     * 打开Session
     * @access public
     * @param string $savePath
     * @param mixed  $sessName
     * @return bool
     * @throws Exception
     */
    public function open($savePath, $sessName) {
        $this->table = db('session');
        return true;
    }

    /**
     * 关闭Session
     * @access public
     */
    public function close() {
        $this->gc($this->lifetime);
        return true;
    }

    /**
     * 读取Session
     * @access public
     * @param string $sessID
     * @return string
     */
    public function read($sessID) {
        $item = $this->table->where(['sessionid' => $sessID])->find();
        $this->_log("Read " . json_encode($item));
        return $item ? $item['data'] : "";
    }

    /**
     * 写入Session
     * @access public
     * @param string $id
     * @param String $data
     * @return bool
     */
    public function write($id, $data) {
        $uid = session('uid');
        $roleid = session('roleid');
        $groupid = session('groupid');
        $m = defined('MODULE_NAME') ? MODULE_NAME : '';
        $c = defined('CONTROLLER_NAME') ? CONTROLLER_NAME : '';
        $a = defined('ACTION_NAME') ? ACTION_NAME : '';
        if (strlen($data) > 255) {
            $data = '';
        }
        $ip = $this->_ip();
        $sessiondata = array(
            'sessionid' => $id,
            'uid' => $uid,
            'ip' => $ip,
            'lastvisit' => time(),
            'roleid' => $roleid,
            'groupid' => $groupid,
            'm' => $m,
            'c' => $c,
            'a' => $a,
            'data' => $data,
        );
        $this->_log("Write " . json_encode($sessiondata));
        $this->table->insert($sessiondata, false, false, true);
        return true;
    }

    /**
     * 删除Session
     * @access public
     * @param string $sessID
     * @return bool
     */
    public function destroy($sessID) {
        $this->table->delete($sessID);
        return true;
    }

    /**
     * Session 垃圾回收
     * @access public
     * @param string $sessMaxLifeTime
     * @return bool
     */
    public function gc($sessMaxLifeTime) {
        return true;
    }

    private function _ip() {
        //strcasecmp 比较两个字符，不区分大小写。返回0，>0，<0。
        if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
            $ip = getenv('HTTP_CLIENT_IP');
        } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
            $ip = getenv('REMOTE_ADDR');
        } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        $res = preg_match('/[\d\.]{7,15}/', $ip, $matches) ? $matches [0] : '';
        return $res;
    }

    private function _log($message) {
        if (APP_DEBUG) {
            error_log("Ticky Session " . $message);
        }
    }

}
